package com.gonsin.ta.logic.spring;

import com.gonsin.ta.logic.annotations.NodeComponent;
import com.gonsin.ta.logic.annotations.NodeMethod;
import com.gonsin.ta.logic.components.RunNode;
import com.gonsin.ta.logic.enums.NodeTypeEnum;
import com.gonsin.ta.logic.exceptions.TaException;
import com.gonsin.ta.logic.components.BaseNode;
import com.gonsin.ta.logic.node.NodeComponentProxy;
import com.gonsin.ta.logic.node.RunNodeProxy;
import com.gonsin.ta.logic.node.SignalNodeProxy;
import com.gonsin.ta.logic.node.SwitchNodeProxy;
import lombok.SneakyThrows;

import java.lang.reflect.Method;

public class NodeProxyUtil {

    /**
     * 根据spring bean对象方法生成节点对象
     */
    public static NodeComponentProxy method2NodeComponent(String nodeId, NodeTypeEnum nodeType, Object bean, String beanName, Method method) {

        if(nodeType == NodeTypeEnum.SWITCH){
            if(!String.class.isAssignableFrom(method.getReturnType())){
                throw new TaException("SWITCH组件方法必须返回String类型");
            }
        }
        NodeMethod nodeMethod = method.getDeclaredAnnotation(NodeMethod.class);

        BaseNode nodeProxy = null;
        switch (nodeType) {
            case RUN:
                nodeProxy = new RunNodeProxy(nodeType, bean, beanName, method);
                break;
            case SIGNAL:
                nodeProxy = new SignalNodeProxy(nodeType, bean, beanName, method);
                break;
            case SWITCH:
                nodeProxy = new SwitchNodeProxy(bean, beanName, method);
        }

        NodeComponentProxy proxy = NodeComponentProxy.builder()
                .nodeId(nodeId)
                .nodeType(nodeType)
                .beanName(beanName)
                .instance(nodeProxy)
                .access(nodeMethod.access())
                .method(method)
                .end(nodeMethod.end())
                .retryCount(nodeMethod.retryCount())
                .build();
        return proxy;
    }

    /**
     * 根据spring bean对象生成节点对象
     */
    public static NodeComponentProxy bean2NodeComponent(NodeComponent nodeComponent, NodeTypeEnum nodeType, Object bean, String beanName) {
        NodeComponentProxy proxy = NodeComponentProxy.builder()
                .nodeId(nodeComponent.nodeId())
                .nodeType(nodeType)
                .instance((BaseNode) bean)
                .beanName(beanName)
                .access(nodeComponent.access())
                .end(nodeComponent.end())
                .retryCount(nodeComponent.retryCount())
                .build();
        return proxy;
    }

    /**
     * 根据spring bean对象生成节点对象
     */
    @SneakyThrows
    public static NodeComponentProxy bean2NodeComponent(String nodeId, NodeTypeEnum nodeType, Class nodeClass) {

        // TODO 补充其他默认值
        NodeComponentProxy proxy = NodeComponentProxy.builder()
                .nodeId(nodeId)
                .nodeType(nodeType)
                .instance((BaseNode) nodeClass.getConstructor().newInstance())
                .beanName(nodeClass.getSimpleName())
                .access(true)
                .end(false)
                .retryCount(3)
                .build();
        return proxy;
    }
}
